iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0

從建立第二個元件認識 Props

在 React 中我們時常會透過元件化,來增加程式碼的重用性,提升易維護性。舉例來說,好幾頁都會出現的搜尋欄、分類 tab 等,就可以拆成元件,再像積木一樣在需要的地方插入。同時當搜尋欄壞掉時,我們也可以直接開啟該檔案修護,不需要在不同頁面、幾百行程式碼中尋找哪行在寫搜尋欄的邏輯?又是哪行壞掉了?

馬上進入實做部分。我們已經有第一個元件 App.jsx 了,現在仿照他的架構,來建立第二個元件 Child.jsx 。習慣上會在根目錄建立 components 資料夾放檔案,統一管理所有元件。再次提醒,元件要以大寫開頭命名!
https://ithelp.ithome.com.tw/upload/images/20230913/20129635KHsIIop6tF.png

import React from 'react';
import {View, Text} from 'react-native';

function Child() {
  return (
    <View>
      <Text>子元件</Text>
    </View>
  );
}

export default Child;

透過 import 引入元件,接著使用上就和 <View> 等元件相同,擺在對應位置即可。以下方例子來說,當 App 元件引入 Child , Child 就成了 App 的子元件, App 則是 Child 的父元件。

import Child from './components/Child';

function App() {
  return (
    <SafeAreaView>
      <View>
        <Child />
      </View>
    </SafeAreaView>
  );
}

export default App;

上述的情景是最單純的一種,不過實務上我們會遇到一些彼此長得 87% 像的東西,偏偏就是有那 13% 的不同。若為了那一點點不同,分好幾個元件,似乎又喪失元件化的初衷。以 Google 首頁下方會出現的捷徑來說,不要跟我說你想把這些拆成十個元件… 那還不如不要拆…
https://ithelp.ithome.com.tw/upload/images/20230913/20129635rIbqgzP275.png

所以我們就會面臨一個問題,怎樣讓同一個元件顯示不同圖片和文字? Props會是這個問題的其中一個解答,他的作用是幫助資料單向從父元件傳進子元件。寫法是將要在子元件使用的名稱放前面,父元件要傳入的資料名稱放後面:

function App() {
  const [parentText, setParentText] = useState('父元件傳進來的文字');
  
  return (
    <Child text={parentText} />

子元件則用下面的方式引入資料:

function Child({text}) {
  return (
    <View>
      <Text>子元件</Text>
      <Text>{text}</Text>
    </View>
  );
}

https://ithelp.ithome.com.tw/upload/images/20230913/2012963536QLCgnELK.png

當然,多引入幾個元件也沒問題。

<Child text={parentText}/>
<Child text="另一個子元件"/>

Tips :稍微補充一下引入資料的寫法演變,最直觀的寫法其實是這樣:

function Child(props) { // 傳入的值一率被 props 這個物件包住
  return (
    {/* 而要取用 props 物件裡的值就要用在父元件取的名稱 */}
    <Text>{props.text}</Text> 
  );
}

不過有了 ES6 的物件解構,我們不用打這麼多字,直接在小括弧指定我們要的屬性名稱就能使用了。

function Child({text}) {
  // {text} 等於直接取用 props.text
  return (
    <Text>{text}</Text>
  );
}

認識正確更新子元件的方式

Props 有一點要注意的,誠如前面所說,他是從父元件單向傳到子元件。換句話說不能從子元件反向傳資料回父元件,再說得更明確一點,我們不能直接去更改 Props 的值。 Props 只是一扇窗,讓子元件能顯示父元件的東西。這是為了避免子元件和父元件各自更新後不一致,產生意料之外的副作用。

要改變在子元件 Props 顯示的內容,唯一方法是父元件的資料被改變了,再藉由 Props 把改變後的內容傳給子元件,使子元件跟著被改變。
https://ithelp.ithome.com.tw/upload/images/20230913/20129635YjfvfLY7DZ.png

以先前的 App 、 Child 來示範,就像下方這樣:

function App() {
  const [parentText, setParentText] = useState('父元件傳進來的文字');

  const handlePress = () => {
    setParentText('父元件傳進來的文字改變了');
  };

  return (
    <Child text={parentText} onPress={handlePress} />

function Child({text, onPress}) {
  return (
    <View>
      <Text>子元件</Text>
      <Text>{text}</Text>
      <TouchableOpacity onPress={onPress}>
        <Text>按下後改變 text</Text>
      </TouchableOpacity>

https://ithelp.ithome.com.tw/upload/images/20230913/20129635wGOqKqC5rz.png


上一篇
Day 10. 深入了解 React 更新 State 機制
下一篇
Day 12. 從實作 Tab 選擇器,認識陣列渲染與動態樣式
系列文
即使明天老闆突然叫你用 React Native 也可以跟他說好沒問題30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言